
from jsonschema import validate
from sanic import Blueprint, Request,json as jsonResp
from app.core.entity import ApiResult
from app.core.exception import ApiException
from app.service.project import ProjectService
from app.service.projectUser import ProjectUserService
from app.utils.RequestUtils import RequestUtils


bp=Blueprint("project",url_prefix="/project")

addProjectSchema={
    "type":"object",
    "properties":{
        "name":{"type":"string"},
    },
    "required":["name"]
}

@bp.route('/get_report_data/<pid>',methods=['GET'])
async def getProjectReportData(request:Request,pid):
    data=ProjectService.getBillData(pid)
    return jsonResp(vars(ApiResult.success(data=data)))

@bp.route('/quit/<pid>',methods=['GET'])
async def quitProject(request:Request,pid):
    ProjectService.quitProject(pid,RequestUtils().getCurrentUserId())
    return jsonResp(vars(ApiResult.success()))


@bp.route('/add',methods=['POST'])
async def add(request:Request):
    postData=request.load_json()
    if postData==None:
        postData={}
    validate(instance=postData,schema=addProjectSchema)
    postData['createdBy']=RequestUtils().getCurrentUserId()
    project=ProjectService.addProject(postData)
    return jsonResp(vars(ApiResult.success(data={"id":project.id})))

updProjectSchema={
    "type":"object",
    "properties":{
        "name":{"type":"string"},
    },
    "required":["name"]
}
@bp.route('/upd',methods=['POST'])
async def upd(request:Request):
    postData=request.load_json()
    if postData==None:
        postData={}
    validate(instance=postData,schema=updProjectSchema)
    postData["id"]=RequestUtils().getCurrentProjectId()
    project=ProjectService.updProject(postData)
    return jsonResp(vars(ApiResult.success(data={"id":project.id})))

@bp.route("/delete/<id>",methods=['POST'])
async def projectDel(request:Request,id):
    ProjectService.deleteProject(id)
    return jsonResp(vars(ApiResult.success()))

@bp.route('/list',methods=['POST'])
async def list(request:Request):
    postData=request.load_json()
    currentUserId=RequestUtils().getCurrentUserId()
    projectList=ProjectService.getMyProjectList(currentUserId)
    respList=[]
    for project in projectList:
        json=project.toJson()
        json['creator_name']=project.getCreator().nickname
        json['count']=project.getProjectPeopleCount()
        respList.append(json)
    return jsonResp(vars(ApiResult.success(data={"list":respList})))

@bp.route('/get/<projectId>',methods=['GET'])
async def get(request:Request,projectId):
    currentUserId=RequestUtils().getCurrentUserId()
    project=ProjectService.getMyProjectData(projectId,currentUserId)
    if project is None:
        raise ApiException("项目不存在或者不是你参与的项目")
    return jsonResp(vars(ApiResult.success(data=project)))

@bp.route('/invite/<projectId>',methods=['GET'])
async def inviteData(request:Request,projectId):
    project=ProjectService.getProjectById(projectId)
    projectJson=project.toJson()
    projectJson['peopleCnt']=project.getProjectPeopleCount()
    cnt=9 if projectJson['peopleCnt']>9 else projectJson['peopleCnt']
    projectUsers=project.getProjectUsersAttr()
    projectJson['peopleList']=[]
    for i in range(cnt):
        userInfo=projectUsers[i].getUserInfoAttr()
        projectJson['peopleList'].append(dict(userInfo))
    return jsonResp(vars(ApiResult.success(data=projectJson)))

@bp.route('/user/list',methods=['GET'])
async def getUserList(request:Request):
    projectId=RequestUtils().getCurrentProjectId()
    users=ProjectService.getUserByProjectId(projectId)
    respList=[]
    for user in users:
        respList.append(user.toJson())
    return jsonResp(vars(ApiResult.success(data={"list":respList})))

addProjectGroupSchema={
    "type":"object",
    "properties":{
        "name":{"type":"string"},
        "projectId":{"type":"number"},
        "num":{"type":"number"},
    },
    "required":["name","projectId","num"]
}

@bp.route('/group/add',methods=['POST'])
async def addProjectGroup(request:Request):
    postData=request.load_json()
    postData['projectId']=RequestUtils().getCurrentProjectId()
    postData['createdBy']=RequestUtils().getCurrentUserId()
    postData['num']=int(postData['num'])
    validate(instance=postData,schema=addProjectGroupSchema)
    ProjectService.addProjectGroup(postData)
    return jsonResp(vars(ApiResult.success()))

@bp.route('/group/list',methods=['GET'])
async def getProjectGroupList(request:Request):
    projectGroups=ProjectService.getProjectGroupList(RequestUtils().getCurrentProjectId())
    respList=[]
    for pg in projectGroups:
        json=pg.toJson()
        json['count']=pg.getPeopleNumAttr()
        json['userList']=[]
        for u in pg.getPeopleListAttr():
            json['userList'].append({
                "id":u.id,
                "nickname":u.nickname,
                "avatarUrl":u.avatarUrl,
            })
        respList.append(json)
    return jsonResp(vars(ApiResult.success(data={"list":respList})))

updProjectGroupSchema={
    "type":"object",
    "properties":{
        "name":{"type":"string"},
        "num":{"type":"number"},
        "userList":{"type":"array"}
    },
    "required":["name","projectId","userList"]
}
@bp.route('/group/upd/<groupId>',methods=['POST'])
async def updProjectGroup(request:Request,groupId):
    postData=request.load_json()
    postData['num']=int(postData['num'])
    validate(instance=postData,schema=updProjectGroupSchema)
    ProjectService.updProjectGroup(groupId,postData)
    return jsonResp(vars(ApiResult.success()))

@bp.route('/group/join/<groupId>',methods=['POST'])
async def joinProjectGroup(request:Request,groupId):
    ProjectService.joinProjectGroup(groupId,RequestUtils().getCurrentUserId())
    return jsonResp(vars(ApiResult.success()))

@bp.route('/group/del/<groupId>',methods=['GET'])
async def delProjectGroup(request:Request,groupId):
    ProjectService.delProjectGroup(groupId)
    return jsonResp(vars(ApiResult.success()))

@bp.route('/group/get/<groupId>',methods=['GET'])
async def getProjectGroup(request:Request,groupId):
    pg=ProjectService.existsProjectGroup(groupId)
    json=pg.toJson()
    json['userList']=[]
    for u in pg.getPeopleListAttr():
        json['userList'].append({
            "id":u.id,
            "nickname":u.nickname,
            "avatarUrl":u.avatarUrl,
        })
    return jsonResp(vars(ApiResult.success(data=json)))

projectInviteSchema={
    "type":"object",
    "properties":{
        "uid":{"type":"number"}
    },
    "required":["uid"]
}

@bp.route("/invite",methods=["POST"])
async def projectInvite(request:Request):
    postData=request.load_json()
    if postData==None:
        postData={}
    validate(instance=postData,schema=projectInviteSchema)  
    req=RequestUtils()
    ProjectService.inviteUser(req.getCurrentProjectId(),req.getCurrentUserId(),postData['uid'])
    return jsonResp(vars(ApiResult.success(msg="邀请成功,等待对方接受...")))

@bp.route("/join/<projectId>",methods=["POST"])
async def projectJoin(request:Request,projectId):
    ProjectUserService.joinProject(projectId,RequestUtils().getCurrentUserId(),"N")
    return jsonResp(vars(ApiResult.success(msg="加入成功是否跳转至项目页面？")))


projectTransferSchema={
    "type":"object",
    "properties":{
        "uid":{"type":"number"}
    },
    "required":["uid"]
}

@bp.route("/transfer/<projectId>",methods=["POST"])
async def projectTransfer(request:Request,projectId):
    postData=request.load_json()
    if postData==None:
        postData={}
    validate(instance=postData,schema=projectTransferSchema)
    ProjectService.transferProject(projectId,postData['uid'])
    return jsonResp(vars(ApiResult.success(msg="加入成功是否跳转至项目页面？")))

projectUserDelSchema={
    "type":"object",
    "properties":{
        "userIds":{"type":"array"},
        "pid":{"type":"number"}
    },
    "required":["userIds","pid"]
}
@bp.route("/user/del",methods=["POST"])
async def projectUserDel(request:Request):
    postData=request.load_json()
    if postData==None:
        postData={}
    validate(instance=postData,schema=projectUserDelSchema)
    ProjectUserService.deleteProjectUsers(postData["pid"],postData["userIds"])
    return jsonResp(vars(ApiResult.success()))